/**
 * 自定义指令，用于对输入元素的值进行格式化和限制。
 * 主要用于数值输入，确保输入符合指定的最大值、最小值和精度。
 */
export default {
  /**
   * 当指令绑定的元素插入到DOM中时调用。
   * @param {HTMLElement} el - 指令绑定的元素。
   * @param {Object} vDir - 指令的参数对象，包含max、min和precision属性。
   */
  inserted(el, vDir) {
    let content;

    // 在输入框按下键盘键时触发的事件处理器
    // vDir.value 有指令的参数
    //按键按下=>只允许输入 数字/小数点
    el.addEventListener("keypress", (event) => {
      let e = event || window.event;
      let inputKey = String.fromCharCode(
        typeof e.charCode === "number" ? e.charCode : e.keyCode
      );
      let re = /\d|\./;
      content = e.target.value;

      /**
       * 阻止输入不符合要求的字符。
       */
      function preventInput() {
        if (e.preventDefault) {
          e.preventDefault();
        } else {
          e.returnValue = false;
        }
      }

      // 如果按下的键不是数字或小数点，且不是Ctrl键，则阻止输入
      if (!re.test(inputKey) && !e.ctrlKey) {
        preventInput();
      }
      if (content.indexOf(".") > -1 && inputKey === ".") {
        // 如果输入框中已有小数点，再次按下小数点键，则阻止输入
        preventInput();
      }
    });

    // 在输入框释放键盘键时触发的事件处理器
    //按键弹起=>并限制最大最小
    el.addEventListener("keyup", (event) => {
      handleData(event);
    });

    // 当输入框失去焦点时触发的事件处理器
    //失去焦点=>保留指定位小数
    el.addEventListener("focusout", (event) => {
      handleData(event);
    });

    /**
     * 处理输入框的值，根据最大值、最小值和精度进行限制和格式化。
     * @param {Event} event - 触发的事件对象。
     */
    function handleData(event) {
      let e = event || window.event;
      content = parseFloat(e.target.value);

      // 如果内容为空，则默认为0.00
      if (!content) {
        content = 0.0;
      }

      // 获取指令的参数最大值和最小值
      // 限制最大最小
      let arg_max = "";
      let arg_min = "";
      if (vDir.value) {
        arg_max = parseFloat(vDir.value.max);
        arg_min = parseFloat(vDir.value.min);
      }

      // 如果指定了最大值且输入值大于最大值，则将输入值设置为最大值
      if (arg_max && content > arg_max) {
        e.target.value = arg_max;
        content = arg_max;
      }

      // 如果指定了最小值且输入值小于最小值，则将输入值设置为最小值
      if (arg_min && content < arg_min) {
        e.target.value = arg_min;
        content = arg_min;
      }

      // 获取指令的精度参数，默认为0（即不保留小数）
      let arg_precision = 0; //默认保留至整数
      if (vDir.value.precision) {
        arg_precision = parseFloat(vDir.value.precision);
      }

      // 根据精度对内容进行四舍五入，并更新输入框的值
      if (String(content).indexOf(".") > -1) {
        e.target.value = content.toFixed(arg_precision);
      } else {
        e.target.value = content;
      }

      // 触发input事件，以确保相关的表单验证和数据绑定能够更新
      e.target.dispatchEvent(new Event("input"));
    }
  },
};
